/*
 * 图片编辑「拖动，排序，缩放」 
 * 返回层级，位置，大小
 */
import * as React from 'react';
import { switchElePosition } from 'utils/utils';
import Dragger from 'components/common/Dragger';
import CropBox from './CropBox';

import Rnd from 'react-rnd';

import { Tooltip, Row, Col, Menu, Dropdown, Button, Icon } from 'antd';
import './Animate.css';
import './EditImage.scss';

interface EditProps {
  onCallback: (images: any[]) => any;
  precisionId: number;
  images: any[];
}
interface EditState {
  images: any[];
  animPreviewIndex: number;

  editImageIndex: number;
  visible: boolean;
}

// 样式动画
const anims = [
  {
    key: 'bounce',
    name: '跳一跳',
  },
  {
    key: 'wobble',
    name: '抖一抖',
  },
  {
    key: 'swing',
    name: '晃一晃',
  },
  {
    key: 'bounceOut',
    name: '心跳',
  },
  {
    key: 'bounceInLeft',
    name: '左边飞入',
  },
  {
    key: 'bounceInRight',
    name: '右边飞入',
  },
  {
    key: 'rotateInUpRight',
    name: '转一转',
  },
  {
    key: 'zoomIn',
    name: '出现',
  },
  {
    key: 'zoomOutUp',
    name: '往上飞走',
  },
  {
    key: 'zoomOutDown',
    name: '往下飞走',
  },
];

class EditImage extends React.Component<EditProps, EditState> {
  cWidth: number;
  cHeight: number;
  static defaultProps: EditProps = {
    onCallback: () => {},
    precisionId: 0,
    images: [],
  };

  constructor(props: EditProps) {
    super(props);

    this.cWidth = 600;
    this.cHeight = 600;

    this.state = {
      images: props.images,
      animPreviewIndex: -1,
      editImageIndex: -1,
      visible: false,
    };
  }

  componentWillReceiveProps(nextProps: any) {
    const { precisionId, images } = nextProps;
    const { precisionId: oldPrecisionId } = this.props;

    if (precisionId !== oldPrecisionId) {
      this.setState({
        images,
        animPreviewIndex: -1,
        editImageIndex: -1,
      });
    }
  }

  // 添加交互图片
  // 保持原图片比例
  handleUploadImageDone = (response: any) => {
    const attachments = response.files;
    let { images } = this.state;

    attachments.map((item: any) => {
      let { width, height } = item.properties;
      const ratio = width / height;
      if (width >= height) {
        if (width > this.cWidth) {
          width = this.cWidth;
        }
        height = width / ratio;
      } else {
        if (height > this.cHeight) {
          height = this.cHeight;
        }
        width = ratio * height;
      }

      images.push({
        width: width / this.cWidth,
        height: height / this.cHeight,
        left: 0,
        top: 0,
        id: item.id,
        url: item.uri,
      });
    });

    this.setState({
      images,
    });
  };

  // 交互图片Gif动画
  handleUploadGifDone = (attachment: any, imageIndex: number) => {
    let { images } = this.state;
    images[imageIndex]['gif'] = attachment.uri;
    images[imageIndex]['anim'] = '';
    this.setState({
      images,
    });
  };

  renderTitle() {
    return (
      <div>
        <h4
          className="text-left test-parser-sub-title"
          style={{ display: 'flex', alignItems: 'center' }}>
          上传图片&nbsp;
          <Dragger key="image" accept="image" selectMax={10} onDone={this.handleUploadImageDone}>
            <Button type="primary">
              <Icon type="picture" />
            </Button>
          </Dragger>
        </h4>
      </div>
    );
  }

  handleResize = (editImageIndex: number, ref: any) => {
    let { images } = this.state;

    const visible = true;
    images[editImageIndex].width = ref.offsetWidth / this.cWidth;
    images[editImageIndex].height = ref.offsetHeight / this.cHeight;

    this.setState({ images, editImageIndex, visible });
  };
  handleDrag = (editImageIndex: number, data: any) => {
    let { images } = this.state;

    const visible = true;
    images[editImageIndex].left = data.x / this.cWidth;
    images[editImageIndex].top = data.y / this.cHeight;

    this.setState({ images, editImageIndex, visible });
  };

  handleItemSorted = (keys: any[]) => {
    const { images } = this.state;
    let sortedImages = [];
    for (let i = 0; i < keys.length; i++) {
      sortedImages[i] = images[keys[i]];
    }
    this.setState({
      images: sortedImages,
    });
  };

  // 保存图片位置信息
  handleSaveImage = () => {
    const { images } = this.state;
    this.props.onCallback(images);
  };

  handleAnimClick = (e: any) => {
    const [imageIndex, anim] = e.key.split('_');
    let { images } = this.state;
    images[imageIndex]['anim'] = anim;
    images[imageIndex]['gif'] = '';
    this.setState({
      images,
      animPreviewIndex: Number(imageIndex),
    });
  };

  handleEditImage = (editImageIndex: number) => {
    const visible = true;

    this.setState({
      visible,
      editImageIndex,
    });
  };

  renderCropBox() {
    const { images, editImageIndex, visible } = this.state;
    const { width, height, top, left } = images[editImageIndex];
    const x = left * this.cWidth;
    const y = top * this.cHeight;
    const w = width * this.cWidth;
    const h = height * this.cHeight;
    const CropBoxProps = { x, y, w, h, visible };
    return <CropBox {...CropBoxProps} />;
  }

  handleImageUp = () => {
    let { images, editImageIndex } = this.state;
    if (editImageIndex >= images.length - 1) {
      return;
    }
    images = switchElePosition(images, editImageIndex, editImageIndex + 1);
    this.setState({
      images,
      editImageIndex: editImageIndex + 1,
    });
  };
  handleImageDown = () => {
    let { images, editImageIndex } = this.state;
    if (editImageIndex <= 0) {
      return;
    }
    images = switchElePosition(images, editImageIndex, editImageIndex - 1);
    this.setState({
      images,
      editImageIndex: editImageIndex - 1,
    });
  };
  handleImageRemove = () => {
    let { images, editImageIndex } = this.state;
    images.splice(editImageIndex, 1);

    this.setState({
      images,
      editImageIndex: -1,
      animPreviewIndex: -1,
    });
  };

  // 点击预览动画开关
  handleImageAnimTogglePreview = () => {
    let { images, editImageIndex, animPreviewIndex } = this.state;
    const { anim, gif } = images[editImageIndex];
    if (!anim && !gif) {
      return;
    }

    this.setState({
      animPreviewIndex: animPreviewIndex >= 0 ? -1 : editImageIndex,
    });
  };

  renderImageAction() {
    const { images, editImageIndex } = this.state;
    const actions = [
      {
        icon: 'arrow-up',
        title: '往上移一层',
        disabled: editImageIndex < 0 || editImageIndex === images.length - 1,
        onClick: this.handleImageUp,
      },
      {
        icon: 'arrow-down',
        title: '往下移一层',
        disabled: editImageIndex < 0 || editImageIndex === 0,
        onClick: this.handleImageDown,
      },
      {
        icon: 'down',
        title: '图片动画',
        disabled: editImageIndex < 0,
        dropdownMenu: this.renderAnimMenu(),
      },
      {
        icon: 'eye-o',
        title: '预览动画开关',
        disabled:
          editImageIndex < 0 ||
          (editImageIndex >= 0 &&
            !images[editImageIndex]['anim'] &&
            !images[editImageIndex]['gif']),
        onClick: this.handleImageAnimTogglePreview,
      },
      {
        icon: 'delete',
        title: '移除图片',
        disabled: editImageIndex < 0,
        onClick: this.handleImageRemove,
      },
    ];

    return actions.map(
      (item: any, index: number) =>
        item.dropdownMenu ? (
          <Dropdown
            key={index}
            disabled={item.disabled}
            overlay={item.dropdownMenu}
            trigger={['click']}>
            <Tooltip title={item.title}>
              <Button disabled={item.disabled} ghost type="primary" style={{ marginRight: 12 }}>
                <Icon type={item.icon} />
              </Button>
            </Tooltip>
          </Dropdown>
        ) : (
          <Tooltip title={item.title} key={index}>
            <Button
              ghost
              type="primary"
              onClick={item.onClick}
              disabled={item.disabled}
              style={{ marginRight: 12 }}>
              <Icon type={item.icon} />
            </Button>
          </Tooltip>
        )
    );
  }

  renderImageItems() {
    const { images, animPreviewIndex, editImageIndex } = this.state;
    return images.map((item: any, index: number) => {
      const isAnimated = item.anim && animPreviewIndex === index;
      let imgClass = '';
      let imgUrl = item.url;

      if (isAnimated) {
        imgClass = 'animated infinite ' + item.anim;
      }
      if (animPreviewIndex === index && item.gif) {
        imgUrl = item.gif;
      }

      return (
        <React.Fragment key={index}>
          {index === editImageIndex && this.renderCropBox()}
          <Rnd
            bounds="parent"
            lockAspectRatio={true}
            size={{ width: 'auto', height: 'auto' }}
            position={{ x: item.left * this.cWidth, y: item.top * this.cHeight }}
            onDrag={(e: any, data: any) => {
              this.handleDrag(index, data);
            }}
            onResize={(e: any, dir: any, ref: any) => {
              this.handleResize(index, ref);
            }}>
            <img
              className={imgClass}
              onClick={(e: any) => {
                e.stopPropagation();
                this.handleEditImage(index);
              }}
              style={{
                top: 0,
                left: 0,
                zIndex: index,
                width: item.width ? item.width * this.cWidth : '100%',
                height: item.height ? item.height * this.cHeight : '100%',
                background: 'none',
                maxWidth: '100%',
                maxHeight: '100%',
              }}
              draggable={false}
              src={imgUrl}
            />
          </Rnd>
        </React.Fragment>
      );
    });
  }

  // 动画选择下拉
  renderAnimMenu = () => {
    const { editImageIndex } = this.state;
    return (
      <Menu>
        <Menu.Item style={{ padding: 12 }}>
          <Dropdown
            trigger={['hover']}
            placement="topCenter"
            overlay={
              <Menu onClick={this.handleAnimClick}>
                {anims.map((anim: any) => {
                  return <Menu.Item key={`${editImageIndex}_${anim.key}`}>{anim.name}</Menu.Item>;
                })}
              </Menu>
            }>
            <div>
              样式动画 <Icon type="down" />
            </div>
          </Dropdown>
        </Menu.Item>
        <Menu.Item style={{ padding: 12 }}>
          <Dragger
            key="image"
            accept="image"
            onDone={(response: any) => {
              this.handleUploadGifDone(response.files[0], editImageIndex);
            }}>
            <div>
              Gif动画 <Icon type="picture" />
            </div>
          </Dragger>
        </Menu.Item>
      </Menu>
    );
  };

  renderDraggerImages() {
    const { images } = this.state;
    return (
      <div className="text-center" style={{ width: this.cWidth, display: 'inline-block' }}>
        <div
          onClick={() => {
            this.setState({
              visible: false,
              editImageIndex: -1,
            });
          }}
          style={{
            position: 'relative',
            display: 'inline-block',
            border: '1px dashed #bec8c8',
            width: this.cWidth,
            height: this.cHeight,
          }}>
          {this.renderImageItems()}
        </div>
        <Row>
          <Col span={19} className="action-menu">
            {this.renderImageAction()}
          </Col>
          <Col span={4} offset={1} className="action-menu-submit" style={{ textAlign: 'center' }}>
            <Tooltip title="保存工作">
              <Button
                ghost
                type="primary"
                disabled={images.length === 0}
                onClick={this.handleSaveImage}>
                <Icon type="save" />
              </Button>
            </Tooltip>
          </Col>
        </Row>
      </div>
    );
  }

  render() {
    return (
      <React.Fragment>
        {this.renderTitle()}
        {this.renderDraggerImages()}
      </React.Fragment>
    );
  }
}

export default EditImage;
